home *** CD-ROM | disk | FTP | other *** search
/ PC-Blue - MS DOS Public Domain Library / PC-Blue MS-DOS Public Domain Library - NYACC.iso / vol142 / treedir3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-12-16  |  6.5 KB  |  286 lines

  1. /*
  2.     TREEDIR  --  Tree directory for MSDOS V2.0 and above.
  3.  
  4.     This program combines TREE and DIR to produce a directory
  5.     of all files in each directory along with date, time and
  6.     file size.
  7.  
  8.     usage:    TREEDIR  [directory]  [/s] [/knnn]
  9.  
  10.     If the directory is omitted, the tree starts with the root
  11.     directory.  Use TREEDIR .  to start from the current directory.
  12.  
  13.     Totals are given for each directory, which includes the
  14.     totals of any sub-directories.     If the /s option is specified
  15.     only the totals are displayed.
  16.  
  17.     This program was primarily written to display the actual
  18.     space used on the hard disk for each directory, and the
  19.     amount of space needed to copy to a diskette.  This is due to
  20.     the allocation cluster of MSDOS: files on  diskette are allocated
  21.     in increments of 1024 bytes while files on the hard disk (10 MB)
  22.     are in 4096 byte chunks.  To see the space that would be taken
  23.     by some other allocation size, use the /k option.  For example,
  24.     to see how much hard disk space would be used by copying all
  25.     the files from the diskette on drive a, type
  26.         treedir a: /k4
  27.  
  28.     The program as written requires Lattice c, version 2.1 or
  29.     higher.  No attempt was made to keep it portable, since
  30.     the dos interface is non-portable by definition.  The Lattice
  31.     conio.h is used instead of stdio.h, resulting in direct console
  32.     i/o and a smaller com file.
  33.  
  34.     The program also requires DOS 2.0 or higher, since it doesn't
  35.     make any sense otherswise.
  36.  
  37.  
  38.                     Alan Losoff
  39.                     Milwaukee, Wisconsin
  40.  
  41.     revisions:
  42.         07-05-84    1.01 test for ^C hit (needed when bypassing standard i/o)
  43.         08-01-84    1.2  add summary /s option
  44.         09-13-84    1.3  add /k other allocation.  clean up format
  45. */
  46.  
  47. #include <conio.h>        /* Lattice direct console I/O */
  48.  
  49. #include <stamp.h>        /* time/date file from my cc.bat */
  50. /* static char *__stamp[] = {"dd/dd/dd", "tt/tt/tt"};    */
  51.  
  52. /* BDOS CALLS */
  53. #define GETFAT 0x3600
  54. #define SETDTA 0x1A00
  55. #define FFIRST 0x4E00
  56. #define FNEXT  0x4F00
  57.  
  58. #define SUBDIR 0x0010        /* attribute for sub directory */
  59.  
  60. #define CTRL_C    3
  61.  
  62. struct XREG            /* for lattice bdos call */
  63. {
  64.     short ax,bx,cx,dx,si,di;
  65. };
  66.  
  67. struct    DIRS            /* dos directory entry */
  68. {
  69.     char    for_dos[21];
  70.     char    attr;
  71.     struct
  72.     {
  73.         unsigned hour : 5;
  74.         unsigned minute : 6;
  75.         unsigned twosec : 5;
  76.     }    time;
  77.     struct
  78.     {
  79.         unsigned year : 7;
  80.         unsigned month : 4;
  81.         unsigned day : 5;
  82.     }    date;
  83.     long    size;
  84.     char    name[13];
  85.     char    fill[85];
  86. };
  87.  
  88. struct    counts
  89. {
  90.     int    files;
  91.     long    blocks;
  92.     long    others;
  93.     long    bytes;
  94. };
  95.  
  96.  
  97. int    _stack    = 10000;    /* set stack size (lattice specific) */
  98.  
  99. static    long    blocksize = 0;    /* cluster size for drive specified */
  100. static    long    othersize = 1024;
  101.  
  102. static    int    summary = 0;    /* switch for summary only */
  103.  
  104.  
  105. #define unit(n, u)  (((n) + (u) - 1) / (u))
  106. #define kbytes(n, u)    unit((n)*(u), 1024)
  107.  
  108. main(argc, argv)
  109. int    argc;
  110. char    *argv[];
  111.  
  112. {
  113.     char    *path;
  114.     int    n;
  115.  
  116.     for (n=1; n<argc; n++)
  117.     {
  118.         if (argv[n][0] == '/')
  119.         switch(argv[n][1])
  120.         {
  121.         case    's':
  122.         case    'S':
  123.             summary = 1;
  124.             break;
  125.         case    'k':
  126.         case    'K':
  127.             othersize = (long) atoi(argv[n] + 2) * 1024;
  128.             if (!othersize)
  129.             othersize = 1024;
  130.             break;
  131.         default:
  132.             break;
  133.         }
  134.     }
  135.  
  136.     path        = (argc > 1 && argv[1][0] != '/') ? argv[1] : "";
  137.     blocksize   = cluster(path);
  138.  
  139.     printf("\nTREEDIR   Tree Directory      version 1.3 compiled%s\n\n",
  140.         __stamp[0]);
  141.     printf("%-36s  %-18sBytes  (%4ld) (%4ld)\n",
  142.            "Filename", summary ? "" : "Date    Time",
  143.         blocksize, othersize);
  144.  
  145.     pdir (path, 0);
  146. }
  147.  
  148. pdir (path, cp)             /* print & total for given path */
  149. char    *path;
  150. struct    counts    *cp;
  151. {
  152.     static    margin = -2;
  153.  
  154.     char    *indent();
  155.     char    newpath[129];
  156.  
  157.     struct    DIRS buf;
  158.     struct    counts    c;
  159.  
  160.     int    r;
  161.     long    n, k;
  162.  
  163.     margin += 2;
  164.     c.bytes = c.files = c.blocks = c.others = 0;
  165.  
  166.  
  167.     for (r = first(path, &buf); !r; r = next(path, &buf))
  168.     {
  169.         kbhit();            /* checks for ^C */
  170.  
  171.         if (*buf.name == '.')
  172.         continue;
  173.  
  174.         if (buf.attr & SUBDIR)
  175.         {
  176.         if (!summary)
  177.             printf("\n\n%-36s", indent(margin, buf.name));
  178.         sprintf(newpath, "%s\\%s", path, buf.name);
  179.         pdir(newpath, &c);
  180.         }
  181.         else
  182.         {
  183.         n = unit(buf.size, blocksize);
  184.         k = unit(buf.size, othersize);
  185.         if  (!summary)
  186.             printf("\n%-36s%2d/%02d/%02d  %2d:%02d %9ld %5ldK %5ldK",
  187.                 indent(margin, buf.name) ,
  188.                 buf.date.month, buf.date.day, buf.date.year+80,
  189.                 buf.time.hour, buf.time.minute,
  190.                 buf.size,
  191.                 kbytes(n, blocksize),
  192.                 kbytes(k, othersize));
  193.         c.files++;
  194.         c.blocks += n;
  195.         c.others += k;
  196.         c.bytes  += buf.size;
  197.         }
  198.     }
  199.     margin -= 2;
  200.     if (summary)
  201.         printf("\n%-41s%4d files %9ld %5ldK %5ldK **",
  202.            path, c.files, c.bytes,
  203.            kbytes(c.blocks, blocksize), kbytes(c.others, othersize));
  204.     else
  205.         printf("\n%-41s%4d files %9ld %5ldK %5ldK **",
  206.            "", c.files, c.bytes,
  207.            kbytes(c.blocks, blocksize), kbytes(c.others, othersize));
  208.  
  209.  
  210.     if (cp)
  211.     {
  212.         cp->blocks += c.blocks;
  213.         cp->others += c.others;
  214.         cp->files  += c.files;
  215.         cp->bytes  += c.bytes;
  216.     }
  217.     return;
  218. }
  219.  
  220. char *
  221. indent (margin, name)            /* indent name to margin */
  222. int    margin;
  223. char    *name;
  224. {
  225.     int    n;
  226.     static    char    work[129];
  227.  
  228.     for (n = 0; n< margin; n++)
  229.         work[n] = ' ';
  230.     strcpy(work + margin, name);
  231.     return (work);
  232. }
  233.  
  234. cluster(dir)                /* return cluster size of disk */
  235. char    *dir;
  236. {
  237.     struct    XREG inregs, outregs;
  238.  
  239.     inregs.dx = dir[1] == ':' ? dir[0] & 0x1F : 0;
  240.     inregs.ax = GETFAT;
  241.     intdos(&inregs, &outregs);
  242.     return (outregs.ax * outregs.cx);
  243. }
  244.  
  245. first (dir, buf)            /* find first directory entry */
  246. char    *dir, *buf;
  247. {
  248.     struct    XREG inregs, outregs;
  249.     char    arg[129];
  250.  
  251.     inregs.ax = SETDTA;
  252.     inregs.dx = (int) buf;
  253.     intdos(&inregs, &outregs);
  254.  
  255.     sprintf(arg, "%s\\????????.???", dir);
  256.     inregs.ax = FFIRST;
  257.     inregs.cx = SUBDIR;
  258.     inregs.dx = (int) (&arg);
  259.     intdos(&inregs, &outregs);
  260.     return (outregs.ax);
  261. }
  262.  
  263. next (dir, buf)             /* find next directory entry */
  264. char    *dir, *buf;
  265. {
  266.     struct    XREG inregs, outregs;
  267.     char    arg[129];
  268.  
  269.     inregs.ax = SETDTA;
  270.     inregs.dx = (int) buf;
  271.     intdos(&inregs, &outregs);
  272.  
  273.     sprintf(arg, "%s\\*.*", dir);
  274.     inregs.ax = FNEXT;
  275.     inregs.cx = SUBDIR;
  276.     inregs.dx = (int) (&arg);
  277.     intdos(&inregs, &outregs);
  278.     return (outregs.ax);
  279. }
  280. ;
  281.     inregs.cx = SUBDIR;
  282.     inregs.dx = (int) (&arg);
  283.     intdos(&inregs, &outregs);
  284.     return (outregs.ax);
  285. }
  286.